package com.derbysoft.synxisadapter.dswitch2.service.impl;

import com.derbysoft.cas.support.client.CasUserService;
import com.derbysoft.synxisadapter.commons.model.User;
import com.derbysoft.synxisadapter.commons.repository.UserRepository;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import java.util.*;

public class CasUserSyncServiceImpl implements Runnable {

    protected static final String[] DEFAULT_ROLE_NAMES = new String[]{"ADMIN"};

    private String groupName;

    private static final Logger LOGGER = LoggerFactory.getLogger(CasUserSyncServiceImpl.class);

    private UserRepository userRepository;

    private CasUserService casUserService;

    @Override
    public void run() {
        LOGGER.info("Begin sync cas users");

        StopWatch stopWatch = new StopWatch("Sync cas users");
        stopWatch.start();

        Set<String> remoteUsers = new HashSet<String>(casUserService.getUsernames(groupName));

        if (CollectionUtils.isNotEmpty(remoteUsers)) {
            Map<String, User> localUserMap = toMap(userRepository.listAll());
            for (String remoteUser : remoteUsers) {
                if (localUserMap.containsKey(remoteUser)) {
                    userRepository.enable(localUserMap.get(remoteUser));
                } else {
                    userRepository.create(remoteUser);
                    if (localUserMap.size() == 0) {
                        userRepository.saveRoles(remoteUser, DEFAULT_ROLE_NAMES);
                    }
                }
            }

            for (User user : localUserMap.values()) {
                if (!remoteUsers.contains(user.getName())) {
                    userRepository.disable(user);
                }
            }
        }


        stopWatch.stop();
        LOGGER.info(stopWatch.prettyPrint());

        LOGGER.info("End sync cas users");
    }

    private Map<String, User> toMap(List<User> users) {
        HashMap<String, User> map = new HashMap<String, User>();
        for (User user : users) {
            map.put(user.getName(), user);
        }
        return map;
    }

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public void setCasUserService(CasUserService casUserService) {
        this.casUserService = casUserService;
    }
}